using System;
using System.Collections.Generic;
using System.Text;
using Barrage.GUI.Elements;
using System.Xml;
using Barrage.Global;
using SlimDX;
using Barrage.Meshes.Text;
using Barrage.GUI.Meshes;
using Barrage.Textures;
using System.Globalization;

namespace Barrage.GUI.Templates.Standard
{
    struct StandardGUIButtonListColorPickerAttributes
    {
        const string XML_SLIDER_LINE_TEXTURE_ATTRIBUTE = "sliderLineTexture";
        const string XML_SLIDER_LINE_HOVER_TEXTURE_ATTRIBUTE = "sliderLineHoverTexture";
        const string XML_SLIDER_MARK_TEXTURE_ATTRIBUTE = "sliderMarkTexture";
        const string XML_TEXTURE_ATTRIBUTE = "texture";
        const string XML_HOVER_TEXTURE_ATTRIBUTE = "hoverTexture";
        const string XML_SLIDER_PADDING_ATTRIBUTE = "sliderPadding";
        const string XML_SLIDER_BORDER_ATTRIBUTE = "sliderBorder";
        const string XML_PADDING_ATTRIBUTE = "padding";
        const string XML_BORDER_ATTRIBUTE = "border";
        const string XML_FONTSIZE_ATTRIBUTE = "fontSize";
        const string XML_TEXTOFFSET_X_ATTRIBUTE = "textOffsetX";
        const string XML_TEXTOFFSET_Y_ATTRIBUTE = "textOffsetY";
        const string XML_SLIDER_MARK_SIZE_X_ATTRIBUTE = "sliderMarkSizeX";
        const string XML_SLIDER_MARK_SIZE_Y_ATTRIBUTE = "sliderMarkSizeY";
        const string XML_PREVIEW_OFFSET_X_ATTRIBUTE = "previewOffsetX";
        const string XML_PREVIEW_OFFSET_Y_ATTRIBUTE = "previewOffsetY";
        const string XML_PREVIEW_SIZE_X_ATTRIBUTE = "previewSizeX";
        const string XML_PREVIEW_SIZE_Y_ATTRIBUTE = "previewSizeY";
        const string XML_PREVIEW_TEXTURE_ATTRIBUTE = "previewTexture";
        
        public string PreviewTexture;
        public string SliderLineTexture;
        public string SliderLineHoverTexture;
        public string SliderMarkTexture;
        public string Texture;
        public string HoverTexture;
        public string SliderCoordBorder;
        public string SliderUVBorder;
        public string CoordBorder;
        public string UVBorder;
        public string BitmapFont;
        public float FontSize;
        public Vector2 TextOffset;
        public Vector2 SliderMarkSize;

        public Vector2 PreviewOffset;
        public Vector2 PreviewSize;

        const string DEFAULT_SLIDER_LINE_TEXTURE = "Standard/buttonListColorPickerLine.png";
        const string DEFAULT_SLIDER_LINE_HOVER_TEXTURE = "Standard/buttonListColorPickerLineHover.png";
        const string DEFAULT_SLIDER_MARK_TEXTURE = "Standard/buttonListSliderMark.png";
        const string DEFAULT_TEXTURE = "Standard/buttonListOption.png";
        const string DEFAULT_HOVER_TEXTURE = "Standard/buttonListOptionHover.png";
        const string DEFAULT_SLIDER_COORDBORDER = "9,9,9,9";
        const string DEFAULT_SLIDER_UVBORDER = "0.03515625,0.28125,0.03515625,0.28125";
        const string DEFAULT_COORDBORDER = "45,45,45,45";
        const string DEFAULT_UVBORDER = "0.0439453125,0.3515625,0.0439453125,0.3515625";
        const string DEFAULT_FONT = "Standard";
        const float DEFAULT_FONTSIZE = 24;
        const float DEFAULT_TEXTOFFSET_X = 0;
        const float DEFAULT_TEXTOFFSET_Y = 35;
        const float DEFAULT_SLIDER_MARK_SIZE_X = 16;
        const float DEFAULT_SLIDER_MARK_SIZE_Y = 16;
        const float DEFAULT_PREVIEW_OFFSET_X = 150;
        const float DEFAULT_PREVIEW_OFFSET_Y = -25;
        const float DEFAULT_PREVIEW_SIZE_X = 40;
        const float DEFAULT_PREVIEW_SIZE_Y = 40;
        const string DEFAULT_PREVIEW_TEXTURE = "Standard/buttonListColorPickerPreview.png";

        public static StandardGUIButtonListColorPickerAttributes DefaultValues
        {
            get
            {
                return new StandardGUIButtonListColorPickerAttributes(
                    Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_TEXTURE,
                    Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_HOVER_TEXTURE,
                    DEFAULT_COORDBORDER,
                    DEFAULT_UVBORDER,
                    DEFAULT_FONT,
                    DEFAULT_FONTSIZE,
                    Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_SLIDER_LINE_TEXTURE,
                    Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_SLIDER_LINE_HOVER_TEXTURE,
                    Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_SLIDER_MARK_TEXTURE,
                    DEFAULT_SLIDER_COORDBORDER,
                    DEFAULT_SLIDER_UVBORDER,
                    new Vector2(DEFAULT_TEXTOFFSET_X, DEFAULT_TEXTOFFSET_Y),
                    new Vector2(DEFAULT_SLIDER_MARK_SIZE_X, DEFAULT_SLIDER_MARK_SIZE_Y),
                    new Vector2(DEFAULT_PREVIEW_OFFSET_X, DEFAULT_PREVIEW_OFFSET_Y),
                    new Vector2(DEFAULT_PREVIEW_SIZE_X, DEFAULT_PREVIEW_SIZE_Y),
                    Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_PREVIEW_TEXTURE
                     );
            }
        }

        public StandardGUIButtonListColorPickerAttributes(string texture, string hoverTexture, string coordBorder, string UVBorder, string BitmapFont, float FontSize, string sliderLineTexture, string sliderLineHoverTexture, string sliderMarkTexture, string sliderCoordBorder, string sliderUVBoorder, Vector2 textOffset, Vector2 sliderMarkSize,Vector2 previewOffset,Vector2 previewSize, string previewTexture)
        {
            this.Texture = texture;
            this.HoverTexture = hoverTexture;
            this.CoordBorder = coordBorder;
            this.UVBorder = UVBorder;
            this.BitmapFont = BitmapFont;
            this.FontSize = FontSize;
            this.SliderLineTexture = sliderLineTexture;
            this.SliderLineHoverTexture = sliderLineHoverTexture;
            this.SliderMarkTexture = sliderMarkTexture;
            this.SliderCoordBorder = sliderCoordBorder;
            this.SliderUVBorder = sliderUVBoorder;
            this.TextOffset = textOffset;
            this.SliderMarkSize = sliderMarkSize;
            this.PreviewOffset = previewOffset;
            this.PreviewSize = previewSize;
            this.PreviewTexture = previewTexture;
        }
        public StandardGUIButtonListColorPickerAttributes(XmlNode xn)
        {
            Texture = XmlHelper.GetXMLAttribute(xn, XML_TEXTURE_ATTRIBUTE, Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_TEXTURE);
            HoverTexture = XmlHelper.GetXMLAttribute(xn, XML_HOVER_TEXTURE_ATTRIBUTE, Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_HOVER_TEXTURE);
            CoordBorder = XmlHelper.GetXMLAttribute(xn, XML_PADDING_ATTRIBUTE, DEFAULT_COORDBORDER);
            UVBorder = XmlHelper.GetXMLAttribute(xn, XML_BORDER_ATTRIBUTE, DEFAULT_UVBORDER);
            BitmapFont = DEFAULT_FONT;
            FontSize = XmlHelper.ParseXMLFloatAttribute(xn, XML_FONTSIZE_ATTRIBUTE, DEFAULT_FONTSIZE);
            SliderLineTexture = XmlHelper.GetXMLAttribute(xn, XML_SLIDER_LINE_TEXTURE_ATTRIBUTE, Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_SLIDER_LINE_TEXTURE);
            SliderLineHoverTexture = XmlHelper.GetXMLAttribute(xn, XML_SLIDER_LINE_HOVER_TEXTURE_ATTRIBUTE, Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_SLIDER_LINE_HOVER_TEXTURE);
            SliderMarkTexture = XmlHelper.GetXMLAttribute(xn, XML_SLIDER_MARK_TEXTURE_ATTRIBUTE, Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_SLIDER_MARK_TEXTURE);
            SliderCoordBorder = XmlHelper.GetXMLAttribute(xn, XML_SLIDER_PADDING_ATTRIBUTE, DEFAULT_SLIDER_COORDBORDER);
            SliderUVBorder = XmlHelper.GetXMLAttribute(xn, XML_SLIDER_BORDER_ATTRIBUTE, DEFAULT_SLIDER_UVBORDER);
            TextOffset = XmlHelper.ParseXMLVector2Attribute(xn, XML_TEXTOFFSET_X_ATTRIBUTE, XML_TEXTOFFSET_Y_ATTRIBUTE, new Vector2(DEFAULT_TEXTOFFSET_X, DEFAULT_TEXTOFFSET_Y));
            SliderMarkSize = XmlHelper.ParseXMLVector2Attribute(xn, XML_SLIDER_MARK_SIZE_X_ATTRIBUTE, XML_SLIDER_MARK_SIZE_Y_ATTRIBUTE, new Vector2(DEFAULT_SLIDER_MARK_SIZE_X, DEFAULT_SLIDER_MARK_SIZE_Y));
            PreviewOffset = XmlHelper.ParseXMLVector2Attribute(xn, XML_PREVIEW_OFFSET_X_ATTRIBUTE, XML_PREVIEW_OFFSET_Y_ATTRIBUTE, new Vector2(DEFAULT_PREVIEW_OFFSET_X, DEFAULT_PREVIEW_OFFSET_Y));
            PreviewSize = XmlHelper.ParseXMLVector2Attribute(xn, XML_PREVIEW_SIZE_X_ATTRIBUTE, XML_PREVIEW_SIZE_Y_ATTRIBUTE, new Vector2(DEFAULT_PREVIEW_SIZE_X, DEFAULT_PREVIEW_SIZE_Y));
            PreviewTexture = XmlHelper.GetXMLAttribute(xn, XML_PREVIEW_TEXTURE_ATTRIBUTE, Store.PathConfig[Store.TEMPLATE_PATH] + DEFAULT_TEXTURE);
        }
    }
    /// <summary>
    /// Standard template implementation of GUIButtonListColorPicker
    /// </summary>
    public class StandardGUIButtonListColorPicker : GUIButtonListColorPicker
    {
        /// <summary>
        /// \internal Size of the item for mouse intersection checking. Can be overrided
        /// </summary>
        protected override Vector2 DefaultSize { get { return new Vector2(450, 139); } }

        /// <summary>
        /// \internal Default size of the slider for mouse intersection checking. Can be overrided
        /// </summary>
        protected override Vector2 DefaultSliderSize { get { return new Vector2(260, 18); } }

        /// <summary>
        /// \internal Default offset of the slider for mouse intersection checking. Can be overrided
        /// </summary>
        protected override Vector2 DefaultSliderOffset { get { return new Vector2(-50, 0); } }

        /// <summary>
        /// \internal Default spacing between component sliders. Can be overrided
        /// </summary>
        protected override float DefaultSliderSpacing { get { return 0; } }

        const string XML_DEFAULT_ATTRIBUTE = "default";
        StandardGUIButtonListColorPickerAttributes attributes;
        TextBoxMesh textMesh;
        SimpleRectangle previewRectangle;
        BorderedRectangle borderedRectangle;
        BorderedRectangle []sliderBorderedRectangle=new BorderedRectangle[3];
        SimpleRectangle[] sliderMark=new SimpleRectangle[3];
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="layout">Layout that will hold this item</param>
        /// <param name="xn">Xml Node that holds attribute values of this item</param>
        public StandardGUIButtonListColorPicker(GUILayout layout, XmlNode xn)
            : base(layout, GUITemplateTypes.Standard, xn)
        {
            processDefaultValues(xn);

            float[] coordBorder = parseBorders(attributes.CoordBorder);
            float[] uvBorder = parseBorders(attributes.UVBorder);

            float[] sliderCoordBorder = parseBorders(attributes.SliderCoordBorder);
            float[] sliderUVBorder = parseBorders(attributes.SliderUVBorder);

            borderedRectangle = new BorderedRectangle(TextureManager.Textures[attributes.Texture], size, coordBorder, uvBorder);
            addMesh(borderedRectangle);

            for (int i = 0; i < 3; i++)
            {
                sliderBorderedRectangle[i] = new BorderedRectangle(TextureManager.Textures[attributes.SliderLineTexture], sliderSize, sliderCoordBorder, sliderUVBorder);
                sliderBorderedRectangle[i].Offset = sliderOffset - new Vector2(0, sliderSize.Y + sliderSpacing) * i;
                addMesh(sliderBorderedRectangle[i]);

                sliderMark[i] = new SimpleRectangle(TextureManager.Textures[attributes.SliderMarkTexture], attributes.SliderMarkSize);
                sliderMark[i].Offset = sliderOffset - new Vector2(0, sliderSize.Y + sliderSpacing) * i;
                addMesh(sliderMark[i]);
            }

            previewRectangle = new SimpleRectangle(TextureManager.Textures[attributes.PreviewTexture], attributes.PreviewSize);
            previewRectangle.Offset = attributes.PreviewOffset;
            addMesh(previewRectangle);

            BitmapFont f = BitmapFontManager.Fonts[attributes.BitmapFont];
            float scale = attributes.FontSize / f.FontInfo.LineHeight;
            textMesh = new TextBoxMesh(f, new TextBoxDrawProperties(TextAlignment.Center, size, scale, VerticalAlignment.Center, attributes.TextOffset));
            textMesh.Text = Text;
            addMesh(textMesh);
        }

        void processDefaultValues(XmlNode xn)
        {
            bool doNotLoadDefaults = XmlHelper.GetXMLAttribute(xn, XML_DEFAULT_ATTRIBUTE).Equals("false");
            if (doNotLoadDefaults)
                attributes = new StandardGUIButtonListColorPickerAttributes(xn);
            else
                attributes = StandardGUIButtonListColorPickerAttributes.DefaultValues;

        }

        /// <summary>
        /// \internal Gets / Sets field label
        /// </summary>
        public override string Text { set { textMesh.Text = value; base.Text = value; } }

        private float[] parseBorders(string source)
        {
            float[] border = new float[4] { 0, 0, 0, 0 };
            if (source.Length == 0) return border;
            string[] borderStrings = source.Split(',');
            for (int i = 0; i < Math.Min(4, borderStrings.Length); i++)
            {
                Single.TryParse(borderStrings[i], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out border[i]);
            }
            return border;
        }

        /// <summary>
        /// \internal Updates matrices and item logic
        /// </summary>
        protected override void DoUpdate()
        {
            for (int i = 0; i < 3; i++)
            {
                float val = ComponentValue((ColorComponent)i);
                sliderMark[i].Offset = new Vector2(-DefaultSliderSize.X / 2f + DefaultSliderSize.X * val, 0) + sliderOffset - new Vector2(0, i * (sliderSize.Y + sliderSpacing));
                val = 0.2f + val * 0.8f;
                switch (i)
                {
                    case 0:
                        sliderBorderedRectangle[i].Materials[0].Diffuse = new Color4(val, 0, 0);
                        break;
                    case 1:
                        sliderBorderedRectangle[i].Materials[0].Diffuse = new Color4(0, val, 0);
                        break;
                    case 2:
                        sliderBorderedRectangle[i].Materials[0].Diffuse = new Color4(0, 0, val);
                        break;
                }
            }
            previewRectangle.Materials[0].Diffuse = new Color4(PickedColor);

            base.DoUpdate();
            UpdateHover();

        }

        void UpdateHover()
        {
            for (int i = 0; i < 3; i++)
            {
                borderedRectangle.Materials[0].Texture = TextureManager.Textures[Selected ? attributes.HoverTexture : attributes.Texture];
                sliderBorderedRectangle[i].Materials[0].Texture = TextureManager.Textures[Selected ? attributes.SliderLineHoverTexture : attributes.SliderLineTexture];
            }
        }

        /// <summary>
        /// \internal Clear resources
        /// </summary>
        public override void Dispose()
        {
            textMesh = null;
            previewRectangle = null;
            borderedRectangle = null;
            sliderBorderedRectangle = null;
            sliderMark = null;
            base.Dispose();
        }
    }
}
